/**
 * @file system_data.c
 * @brief 系统数据模块实现
 * @details 本文件实现了104协议的系统数据处理功能，包括总召唤命令、
 *          初始化命令、复位进程命令、时钟同步命令等数据类型的
 *          序列化和反序列化操作。支持完整的数据转换和验证功能。
 * 
 * @author zyb
 * @date 2025-10-13
 * @version 1.0
 * 
 * @note 所有函数都遵循104协议规范，确保严格的数据处理
 * @warning 数据转换失败时应返回相应的错误码，便于上层处理
 * 
 * @see system_data.h
 * @see protocol_types.h
 * @see buffer_utils.h
 * @see time_utils.h
 */

#include "../include/system_data.h"
#include "../../common/types/include/protocol_types.h"
#include "../../../../../common/utils/include/buffer_utils.h"
#include "../../common/utils/include/time_utils.h"
#include "../../common/error/include/error_codes.h"
#include "../../common/utils/include/validation_utils.h"
#include "../../../../../common/logs/include/logger.h"
#include <string.h>

// 定义模块名称
#define LOG_MODULE_NAME "SYSTEM_DATA"

/* ==================== 总召唤命令处理函数实现 ==================== */

/**
 * @brief 总召唤命令转换为字节数组
 * @details 将总召唤命令结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param command 总召唤命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_general_interrogation_command
 * @see validate_general_interrogation_command
 * @see buffer_write_u32
 * @see buffer_write_u8
 */
protocol_error_t general_interrogation_command_to_bytes(const C_IC_NA_1_t* command,
                                                      u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换总召唤命令到字节数组: command=%p, buffer=%p, buffer_size=%u", 
              command, buffer, buffer_size);
    
    if (command == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证总召唤命令 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证信息对象地址: %u", command->info_address);
    if (!(command->info_address == 0)) {
        LOG_ERROR(LOG_MODULE_NAME, "总召唤命令信息对象地址必须为0，实际值: %u", command->info_address);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "总召唤命令信息对象地址验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 4) { /* 地址(3字节) + QOI(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 4", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 4", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: %u", command->info_address);
    buffer_write_u32(buffer, 0, command->info_address, 0);
    
    /* 写入召唤限定词 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入召唤限定词，大小: %zu", sizeof(qoi_interrogation_t));
    memcpy(&buffer[3], &command->qualifier, sizeof(qoi_interrogation_t));
    
    *actual_length = 4;
    LOG_INFO(LOG_MODULE_NAME, "总召唤命令成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为总召唤命令
 * @details 将104协议规定的字节数组格式转换为总召唤命令结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param command 总召唤命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳总召唤命令
 * 
 * @see general_interrogation_command_to_bytes
 * @see validate_general_interrogation_command
 * @see buffer_read_u32
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_general_interrogation_command(const u8* data, u32 length,
                                                      C_IC_NA_1_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换总召唤命令: data=%p, length=%u, command=%p", 
              data, length, command);
    
    if (data == NULL || command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 4) { /* 地址(3字节) + QOI(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 4", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 4", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&command->info_address, 0);
    
    /* 读取召唤限定词 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取召唤限定词从缓冲区[3]");
    command->qualifier = *(qoi_interrogation_t*)&data[3];
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=%u, QOI=0x%02X", 
              command->info_address, *(u8*)&command->qualifier);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!(command->info_address == 0)) {
        LOG_ERROR(LOG_MODULE_NAME, "总召唤命令信息对象地址必须为0，实际值: %u", command->info_address);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "总召唤命令转换成功: 地址=%u, QOI=0x%02X", 
             command->info_address, *(u8*)&command->qualifier);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证总召唤命令
 * @details 验证总召唤命令结构的完整性和有效性。
 *          检查地址和召唤限定词的有效性。
 * 
 * @param command 总召唤命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 总召唤命令有效
 *         - 0: 总召唤命令无效
 * 
 * @note 验证地址和召唤限定词的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_qoi_valid
 * @see C_IC_NA_1_t
 */
int validate_general_interrogation_command(const C_IC_NA_1_t* command) {
    if (command == NULL) {
        return 0;
    }
    
    return (is_info_address_valid(command->info_address) && 
            1);
}

/* ==================== 初始化命令处理函数实现 ==================== */

/**
 * @brief 初始化命令转换为字节数组
 * @details 将初始化命令结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param command 初始化命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_initialization_command
 * @see validate_initialization_command
 * @see buffer_write_u32
 * @see buffer_write_u8
 */
protocol_error_t initialization_command_to_bytes(const C_CI_NA_1_t* command,
                                               u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换初始化命令到字节数组: command=%p, buffer=%p, buffer_size=%u", 
              command, buffer, buffer_size);
    
    if (command == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证初始化命令 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证信息对象地址: %u", command->info_address);
    if (!(command->info_address == 0)) {
        LOG_ERROR(LOG_MODULE_NAME, "初始化命令信息对象地址必须为0，实际值: %u", command->info_address);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "初始化命令信息对象地址验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 4) { /* 地址(3字节) + COI(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 4", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 4", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: %u", command->info_address);
    buffer_write_u32(buffer, 0, command->info_address, 0);
    
    /* 写入初始化原因 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入初始化原因，大小: %zu", sizeof(qoi_interrogation_t));
    memcpy(&buffer[3], &command->qualifier, sizeof(qoi_interrogation_t));
    
    *actual_length = 4;
    LOG_INFO(LOG_MODULE_NAME, "初始化命令成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为初始化命令
 * @details 将104协议规定的字节数组格式转换为初始化命令结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param command 初始化命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳初始化命令
 * 
 * @see initialization_command_to_bytes
 * @see validate_initialization_command
 * @see buffer_read_u32
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_initialization_command(const u8* data, u32 length,
                                                C_CI_NA_1_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换初始化命令: data=%p, length=%u, command=%p", 
              data, length, command);
    
    if (data == NULL || command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 4) { /* 地址(3字节) + COI(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 4", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 4", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&command->info_address, 0);
    
    /* 读取初始化原因 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取初始化原因从缓冲区[3]");
    memcpy(&command->qualifier, &data[3], sizeof(qoi_t));
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=%u, COI=0x%02X", 
              command->info_address, *(u8*)&command->qualifier);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!(command->info_address == 0)) {
        LOG_ERROR(LOG_MODULE_NAME, "初始化命令信息对象地址必须为0，实际值: %u", command->info_address);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "初始化命令转换成功: 地址=%u, COI=0x%02X", 
             command->info_address, *(u8*)&command->qualifier);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证初始化命令
 * @details 验证初始化命令结构的完整性和有效性。
 *          检查地址和初始化原因的有效性。
 * 
 * @param command 初始化命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 初始化命令有效
 *         - 0: 初始化命令无效
 * 
 * @note 验证地址和初始化原因的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_qoi_valid
 * @see C_CI_NA_1_t
 */
int validate_initialization_command(const C_CI_NA_1_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证初始化命令: command=%p", command);
    
    if (command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    int valid = (is_info_address_valid(command->info_address) && 1);
    LOG_INFO(LOG_MODULE_NAME, "初始化命令验证结果: %s", valid ? "有效" : "无效");
    return valid;
}

/* ==================== 复位进程命令处理函数实现 ==================== */

/**
 * @brief 复位进程命令转换为字节数组
 * @details 将复位进程命令结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param command 复位进程命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_reset_process_command
 * @see validate_reset_process_command
 * @see buffer_write_u32
 * @see buffer_write_u8
 */
protocol_error_t reset_process_command_to_bytes(const C_RP_NA_1_t* command,
                                               u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换复位进程命令到字节数组: command=%p, buffer=%p, buffer_size=%u", 
              command, buffer, buffer_size);
    
    if (command == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证复位进程命令 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证信息对象地址: %u", command->info_address);
    if (!(command->info_address == 0)) {
        LOG_ERROR(LOG_MODULE_NAME, "复位进程命令信息对象地址必须为0，实际值: %u", command->info_address);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "复位进程命令信息对象地址验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 4) { /* 地址(3字节) + QRP(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 4", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 4", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: %u", command->info_address);
    buffer_write_u32(buffer, 0, command->info_address, 0);
    
    /* 写入复位进程命令限定词 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入复位进程命令限定词，大小: %zu", sizeof(qoi_interrogation_t));
    memcpy(&buffer[3], &command->qualifier, sizeof(qoi_interrogation_t));
    
    *actual_length = 4;
    LOG_INFO(LOG_MODULE_NAME, "复位进程命令成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为复位进程命令
 * @details 将104协议规定的字节数组格式转换为复位进程命令结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param command 复位进程命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳复位进程命令
 * 
 * @see reset_process_command_to_bytes
 * @see validate_reset_process_command
 * @see buffer_read_u32
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_reset_process_command(const u8* data, u32 length,
                                              C_RP_NA_1_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换复位进程命令: data=%p, length=%u, command=%p", 
              data, length, command);
    
    if (data == NULL || command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 4) { /* 地址(3字节) + QRP(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 4", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 4", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&command->info_address, 0);
    
    /* 读取复位进程命令限定词 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取复位进程命令限定词从缓冲区[3]");
    command->qualifier = *(qrp_t*)&data[3];
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=%u, QRP=0x%02X", 
              command->info_address, *(u8*)&command->qualifier);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!(command->info_address == 0)) {
        LOG_ERROR(LOG_MODULE_NAME, "复位进程命令信息对象地址必须为0，实际值: %u", command->info_address);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "复位进程命令转换成功: 地址=%u, QRP=0x%02X", 
             command->info_address, *(u8*)&command->qualifier);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证复位进程命令
 * @details 验证复位进程命令结构的完整性和有效性。
 *          检查地址和复位进程命令限定词的有效性。
 * 
 * @param command 复位进程命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 复位进程命令有效
 *         - 0: 复位进程命令无效
 * 
 * @note 验证地址和复位进程命令限定词的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_reset_valid
 * @see C_RP_NA_1_t
 */
int validate_reset_process_command(const C_RP_NA_1_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证复位进程命令: command=%p", command);
    
    if (command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    int valid = (is_info_address_valid(command->info_address) && 1);
    LOG_INFO(LOG_MODULE_NAME, "复位进程命令验证结果: %s", valid ? "有效" : "无效");
    return valid;
}

/* ==================== 时钟同步命令处理函数实现 ==================== */

/**
 * @brief 时钟同步命令转换为字节数组
 * @details 将时钟同步命令结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param command 时钟同步命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 时间戳无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_clock_sync_command
 * @see validate_clock_sync_command
 * @see buffer_write_u32
 * @see cp56time2a_to_bytes
 */
protocol_error_t clock_sync_command_to_bytes(const C_CS_NA_1_t* command,
                                            u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换时钟同步命令到字节数组: command=%p, buffer=%p, buffer_size=%u", 
              command, buffer, buffer_size);
    
    if (command == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证时钟同步命令 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证信息对象地址: %u", command->info_address);
    if (!is_info_address_valid(command->info_address)) {
        LOG_ERROR(LOG_MODULE_NAME, "时钟同步命令信息对象地址无效: %u", command->info_address);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "时钟同步命令信息对象地址验证通过");
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证时间戳");
    if (!is_cp56time2a_valid(&command->timestamp)) {
        LOG_ERROR(LOG_MODULE_NAME, "时钟同步命令时间戳无效");
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "时钟同步命令时间戳验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 10) { /* 地址(3字节) + 时间戳(7字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 10", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 10", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: %u", command->info_address);
    buffer_write_u32(buffer, 0, command->info_address, 0);
    
    /* 写入时间戳 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入时间戳，大小: 7字节");
    memcpy(&buffer[3], &command->timestamp, 7);
    protocol_error_t result = PROTOCOL_SUCCESS;
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "时间戳写入失败");
        return result;
    }
    
    *actual_length = 10;
    LOG_INFO(LOG_MODULE_NAME, "时钟同步命令成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为时钟同步命令
 * @details 将104协议规定的字节数组格式转换为时钟同步命令结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param command 时钟同步命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 时间戳无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳时钟同步命令
 * 
 * @see clock_sync_command_to_bytes
 * @see validate_clock_sync_command
 * @see buffer_read_u32
 * @see bytes_to_cp56time2a
 */
protocol_error_t bytes_to_clock_sync_command(const u8* data, u32 length,
                                           C_CS_NA_1_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换时钟同步命令: data=%p, length=%u, command=%p", 
              data, length, command);
    
    if (data == NULL || command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 10) { /* 地址(3字节) + 时间戳(7字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 10", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 10", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&command->info_address, 0);
    
    /* 读取时间戳 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取时间戳从缓冲区[3-9]");
    memcpy(&command->timestamp, &data[3], 7);
    protocol_error_t result = PROTOCOL_SUCCESS;
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "时间戳读取失败");
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=%u", command->info_address);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!is_info_address_valid(command->info_address)) {
        LOG_ERROR(LOG_MODULE_NAME, "时钟同步命令信息对象地址无效: %u", command->info_address);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_cp56time2a_valid(&command->timestamp)) {
        LOG_ERROR(LOG_MODULE_NAME, "时钟同步命令时间戳无效");
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "时钟同步命令转换成功: 地址=%u", command->info_address);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证时钟同步命令
 * @details 验证时钟同步命令结构的完整性和有效性。
 *          检查地址和时间戳的有效性。
 * 
 * @param command 时钟同步命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 时钟同步命令有效
 *         - 0: 时钟同步命令无效
 * 
 * @note 验证地址和时间戳的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_cp56time2a_valid
 * @see C_CS_NA_1_t
 */
int validate_clock_sync_command(const C_CS_NA_1_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证时钟同步命令: command=%p", command);
    
    if (command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    int valid = (is_info_address_valid(command->info_address) && 
                 is_cp56time2a_valid(&command->timestamp));
    LOG_INFO(LOG_MODULE_NAME, "时钟同步命令验证结果: %s", valid ? "有效" : "无效");
    return valid;
}

/* ==================== 辅助函数实现 ==================== */

/**
 * @brief 获取总召唤命令大小
 * @details 获取总召唤命令结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 总召唤命令大小（字节）
 * 
 * @note 总召唤命令大小：4字节（地址3字节 + QOI1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_initialization_command_size
 * @see get_reset_process_command_size
 * @see C_IC_NA_1_t
 */
u32 get_general_interrogation_command_size(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取总召唤命令大小");
    u32 size = 4; /* 地址(3字节) + QOI(1字节) */
    LOG_INFO(LOG_MODULE_NAME, "总召唤命令大小: %u字节", size);
    return size;
}

/**
 * @brief 获取初始化命令大小
 * @details 获取初始化命令结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 初始化命令大小（字节）
 * 
 * @note 初始化命令大小：4字节（地址3字节 + COI1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_general_interrogation_command_size
 * @see get_reset_process_command_size
 * @see C_CI_NA_1_t
 */
u32 get_initialization_command_size(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取初始化命令大小");
    u32 size = 4; /* 地址(3字节) + COI(1字节) */
    LOG_INFO(LOG_MODULE_NAME, "初始化命令大小: %u字节", size);
    return size;
}

/**
 * @brief 获取复位进程命令大小
 * @details 获取复位进程命令结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 复位进程命令大小（字节）
 * 
 * @note 复位进程命令大小：4字节（地址3字节 + QRP1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_general_interrogation_command_size
 * @see get_initialization_command_size
 * @see C_RP_NA_1_t
 */
u32 get_reset_process_command_size(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取复位进程命令大小");
    u32 size = 4; /* 地址(3字节) + QRP(1字节) */
    LOG_INFO(LOG_MODULE_NAME, "复位进程命令大小: %u字节", size);
    return size;
}

/**
 * @brief 获取时钟同步命令大小
 * @details 获取时钟同步命令结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 时钟同步命令大小（字节）
 * 
 * @note 时钟同步命令大小：10字节（地址3字节 + 时间戳7字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_general_interrogation_command_size
 * @see get_initialization_command_size
 * @see C_CS_NA_1_t
 */
u32 get_clock_sync_command_size(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取时钟同步命令大小");
    u32 size = 10; /* 地址(3字节) + 时间戳(7字节) */
    LOG_INFO(LOG_MODULE_NAME, "时钟同步命令大小: %u字节", size);
    return size;
}

/* ==================== 限定词验证函数实现 ==================== */

/**
 * @brief 验证召唤限定词
 * @details 验证QOI（召唤限定词）是否在104协议规定的有效范围内。
 *          检查保留位是否都为0。
 * 
 * @param qoi 召唤限定词
 * @return 验证结果
 *         - 1: QOI有效
 *         - 0: QOI无效
 * 
 * @note QOI只有7位有效，其他位必须为0
 * @warning 保留位必须为0
 * 
 * @see is_qoi_valid
 * @see is_reset_valid
 * @see qoi_t
 */
int is_qoi_valid_system(const qoi_interrogation_t* qoi) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证召唤限定词: qoi=%p", qoi);
    
    if (qoi == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    /* QOI只有7位有效，其他位必须为0 */
    int valid = (qoi->res == 0);
    LOG_INFO(LOG_MODULE_NAME, "召唤限定词验证结果: %s", valid ? "有效" : "无效");
    return valid;
}

/**
 * @brief 验证初始化原因
 * @details 验证COI（初始化原因）是否在104协议规定的有效范围内。
 *          检查保留位是否都为0。
 * 
 * @param coi 初始化原因
 * @return 验证结果
 *         - 1: COI有效
 *         - 0: COI无效
 * 
 * @note COI只有7位有效，其他位必须为0
 * @warning 保留位必须为0
 * 
 * @see is_qoi_valid
 * @see is_reset_valid
 * @see coi_t
 */
int is_coi_valid(const coi_t* coi) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证初始化原因: coi=%p", coi);
    
    if (coi == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    /* COI只有7位有效，其他位必须为0 */
    int valid = (coi->res == 0);
    LOG_INFO(LOG_MODULE_NAME, "初始化原因验证结果: %s", valid ? "有效" : "无效");
    return valid;
}

/**
 * @brief 验证复位进程命令限定词
 * @details 验证QRP（复位进程命令限定词）是否在104协议规定的有效范围内。
 *          检查保留位是否都为0。
 * 
 * @param qrp 复位进程命令限定词
 * @return 验证结果
 *         - 1: QRP有效
 *         - 0: QRP无效
 * 
 * @note QRP只有7位有效，其他位必须为0
 * @warning 保留位必须为0
 * 
 * @see is_qoi_valid
 * @see is_qoi_valid
 * @see qrp_t
 */
int is_reset_valid(const qrp_t* qrp) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证复位进程命令限定词: qrp=%p", qrp);
    
    if (qrp == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    /* QRP只有7位有效，其他位必须为0 */
    int valid = (qrp->res == 0);
    LOG_INFO(LOG_MODULE_NAME, "复位进程命令限定词验证结果: %s", valid ? "有效" : "无效");
    return valid;
}

/* ==================== 系统命令类型处理函数实现 ==================== */

/**
 * @brief 获取系统命令类型名称
 * @details 根据系统命令类型枚举值获取对应的中文名称。
 *          用于调试和日志输出。
 * 
 * @param type 系统命令类型枚举值
 * @return 系统命令类型名称字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知类型"
 * 
 * @see system_command_type_t
 * @see get_system_command_type_description
 */
const char* get_system_command_type_name(system_command_type_t type) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取系统命令类型名称: type=%d", type);
    
    const char* name;
    switch (type) {
        case SYSTEM_CMD_ENERGY_INTERROGATION:
            name = "总召唤命令";
            break;
        case SYSTEM_CMD_INITIALIZATION:
            name = "初始化命令";
            break;
        case SYSTEM_CMD_RESET_PROCESS:
            name = "复位进程命令";
            break;
        case SYSTEM_CMD_CLOCK_SYNC:
            name = "时钟同步命令";
            break;
        default:
            name = "未知类型";
            break;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "系统命令类型名称: %s", name);
    return name;
}

/**
 * @brief 获取系统命令类型描述
 * @details 根据系统命令类型枚举值获取对应的详细描述。
 *          用于调试和日志输出。
 * 
 * @param type 系统命令类型枚举值
 * @return 系统命令类型描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知类型"
 * 
 * @see system_command_type_t
 * @see get_system_command_type_name
 */
const char* get_system_command_type_description(system_command_type_t type) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取系统命令类型描述: type=%d", type);
    
    const char* description;
    switch (type) {
        case SYSTEM_CMD_ENERGY_INTERROGATION:
            description = "总召唤命令，用于请求所有数据";
            break;
        case SYSTEM_CMD_INITIALIZATION:
            description = "初始化命令，用于初始化通信";
            break;
        case SYSTEM_CMD_RESET_PROCESS:
            description = "复位进程命令，用于复位进程";
            break;
        case SYSTEM_CMD_CLOCK_SYNC:
            description = "时钟同步命令，用于同步时钟";
            break;
        default:
            description = "未知类型";
            break;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "系统命令类型描述: %s", description);
    return description;
}
